package br.unifor.g2cl;

import java.io.IOException;
import java.net.SocketAddress;

import net.sf.jgcs.Annotation;
import net.sf.jgcs.ClosedSessionException;
import net.sf.jgcs.ExceptionListener;
import net.sf.jgcs.GroupConfiguration;
import net.sf.jgcs.JGCSException;
import net.sf.jgcs.Message;
import net.sf.jgcs.MessageListener;
import net.sf.jgcs.Service;
import net.sf.jgcs.ServiceListener;
import net.sf.jgcs.UnsupportedServiceException;

/**
 * Adapter used to implement decorator services easily. Provides the common methods and infra-structure needed. 
 * 
 * @author Henrique Teofilo (henriquetft@gmail.com)
 * 
 */
public class DataSessionAdapter implements IMarshalDataSession, ExceptionListener,
MessageListener, ServiceListener {
	
	protected IMarshalDataSession data;
	protected ExceptionListener realExceptionListener;
	protected MessageListener realMessageListener;
	protected ServiceListener realServiceListener;
	
	
	public DataSessionAdapter(IMarshalDataSession data) {
		this.data = data;
	}
	
	public void close() {
		data.close();
	}

	/**
	 * Creates a message to be sent to the group
	 */
	public Message createMessage() throws ClosedSessionException {
		return data.createMessage();
	}

	public GroupConfiguration getGroup() {
		return data.getGroup();
	}
	
	/**
	 * Forwards the message to the next data session in the chain
	 */
	public void multicast(Message msg, Service service, Object cookie,
			Annotation... annotation) throws IOException,
			UnsupportedServiceException {
		data.multicast(msg, service, cookie, annotation);
	}

	/**
	 * Forwards the message to the next data session in the chain
	 */
	public void send(Message msg, Service service, Object cookie,
			SocketAddress destination, Annotation... annotation)
			throws IOException, UnsupportedServiceException {
			data.send(msg, service, cookie, destination, annotation);
	}

	public void setExceptionListener(ExceptionListener exception)
			throws ClosedSessionException {
		this.realExceptionListener = exception;
		data.setExceptionListener(this);
	}

	/**
	 * Used to specify a message listener
	 */
	public void setMessageListener(MessageListener listener)
			throws ClosedSessionException {
		this.realMessageListener = listener;
		data.setMessageListener(this);
	}

	public void setServiceListener(ServiceListener listener)
			throws ClosedSessionException {
		this.realServiceListener = listener;
		data.setServiceListener(this);
	}
	
	public void onException(JGCSException exception) {
		realExceptionListener.onException(exception);
	}

	public void onServiceEnsured(Object context, Service service) {
		realServiceListener.onServiceEnsured(context, service);
	}
	
	
	public void onExcluded() {

	}
	
	/**
	 * Notify the message listener when a message is received
	 */
	public Object onMessage(Message msg) {
		return realMessageListener.onMessage(msg);
	}


}
